package com.demo.connectdbtest.module.dict.controller;

import com.alibaba.fastjson.JSONObject;
import com.demo.connectdbtest.module.dict.domain.ActivityGoldConsume;
import com.demo.connectdbtest.module.dict.domain.MessageStyleDict;
import com.demo.connectdbtest.module.dict.domain.RewardDataVo;
import com.demo.connectdbtest.module.dict.domain.StatGoldConsumeStatistics;
import com.demo.connectdbtest.module.dict.domain.TotalStatCharge;
import com.demo.connectdbtest.module.dict.meMapper.MessageStyleDictMapper;
import com.demo.connectdbtest.module.price.popoMapper.PriceMapper;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationOperation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.aggregation.TypedAggregation;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @Author
 * @Date 10:46 2021/12/20
 * @Description
 */

@RestController
@RequestMapping("/dict")
public class DictionaryController {

    private static final Logger log = LoggerFactory.getLogger(DictionaryController.class);

    @Autowired
    private MessageStyleDictMapper messageStyleDictMapper;

    @Autowired
    private PriceMapper priceMapper;

    @Autowired
    private MongoTemplate mongoTemplate;


    @GetMapping("/getConsumeGold")
    public String getConsumeGold() {
        List<StatGoldConsumeStatistics> statGoldConsumeStatistics = null;
        try {
            ArrayList<Long> list = new ArrayList<>();
            list.add(1L);
            list.add(2L);
            statGoldConsumeStatistics = priceMapper.listConsumeRecordByBatchUid(list);
            log.info("从库里面获取的数据data={}", JSONObject.toJSONString(statGoldConsumeStatistics));
        } catch (Exception e) {
            log.debug("getConsumeGolderror={}", e);
            return "fail";
        }
        return "ok" + JSONObject.toJSONString(statGoldConsumeStatistics);
    }

    @GetMapping("/getMessageStyle")
    public String getMessageStyle() {
        try {
            MessageStyleDict messageStyleDict = messageStyleDictMapper.selectById(1);
            log.info("从库里面获取的数据data={}", messageStyleDict);
            String content = messageStyleDict.getContent();
            JSONObject jsonObject = JSONObject.parseObject(content);
            String color = jsonObject.getString("color");
            String needlineFeed = jsonObject.getString("needlineFeed");
            log.info("解析的参数color={},needlineFeed={}", color, needlineFeed);
        } catch (Exception e) {
            return "fail";
        }
        return "ok";
    }

    @GetMapping("/getMogonData")
    public String getMogonData() {
        List<TotalStatCharge> userTotalChargeAmount = null;
        try {
            //1-26
            //21-4-7 1617811199000
//            1617724800000L,1617811199000L
            userTotalChargeAmount = getUserTotalChargeAmount(1617724800000L, 1617811199000L);
            //userTotalChargeAmount = getUserBeforeChargeRecord(1617811199000L);
            JSONObject.toJSONString(userTotalChargeAmount);
        } catch (Exception e) {
            log.error("getMogonData", e);
            return "fail" + e.toString();
        }
        return "ok" + JSONObject.toJSONString(userTotalChargeAmount).toString();
    }

    @GetMapping("/getRewardData")
    public String getRewardData(@RequestParam("uidList") String uidList) {
        List<Long> uidsList = new ArrayList<>();

        if (!StringUtils.isEmpty(uidList)) {
            String[] uidArray = uidList.split(",");
            for (String uidStr : uidArray) {
                uidsList.add(Long.parseLong(uidStr));
            }
        }
        log.debug("uidsList={}", JSONObject.toJSONString(uidsList));
        List<RewardDataVo> list = null;
        try {
            Criteria criteria = new Criteria();
            List<AggregationOperation> aggregationList = new ArrayList<>();
            aggregationList.add(Aggregation.match(criteria));
//            aggregationList.add(Aggregation.project("anchorUid","anchorUuid","guiId","giftStream"));
            aggregationList.add(Aggregation.group("anchorUid").sum("giftStream").as("giftStream").first("anchorUuid").as("anchorUuid").first("guiId").as("guiId")
                    .first("anchorUid").as("anchorUid"));
            Aggregation aggregation = Aggregation.newAggregation(aggregationList);
            AggregationResults<RewardDataVo> aggregate = mongoTemplate.aggregate(aggregation, "rewardRecord_2022@5", RewardDataVo.class);
            list = aggregate.getMappedResults();
            log.debug("查询的结果list={}", JSONObject.toJSONString(list));
        } catch (Exception e) {
            log.error("getMogonData", e);
            return "fail" + e.toString();
        }
        return "ok" + JSONObject.toJSONString(list);
    }


    /**
     * 从mongo中获取用户 今天累计充值金额
     */
    private List<TotalStatCharge> getUserTotalChargeAmount(long startTime, long endTime) {
        Criteria criteria = Criteria.where("rechargeTime").gte(startTime).lte(endTime);
        TypedAggregation<TotalStatCharge> chargeRecordAggregation = Aggregation.newAggregation(TotalStatCharge.class,
                Aggregation.match(criteria),
                Aggregation.project("rechargeTime", "uid", "rechargeType", "amount").andExpression("{$dateToString: {date: { $add: {'$rechargeTime', [0]} }, format: '%Y-%m-%d'}}", new Date(28800000)).as("rechargeTime"),
                Aggregation.group("uid", "rechargeType")
                        .first("uid").as("uid")
                        .first("rechargeType").as("rechargeType")
                        .first("rechargeTime").as("rechargeTime")
//                        .sum("amount").as("amount")
                        //.sum("amount").as("currencyAmount")
                        .sum("amount").as("amount"));
        AggregationResults<TotalStatCharge> rechargeRecord = mongoTemplate.aggregate(chargeRecordAggregation, "rechargeRecord", TotalStatCharge.class);
        return rechargeRecord.getMappedResults();
    }


    private List<TotalStatCharge> getUserBeforeChargeRecord(long endTime) {
        Criteria criteria = Criteria.where("rechargeTime").lte(endTime);
        TypedAggregation<TotalStatCharge> chargeRecordAggregation = Aggregation.newAggregation(TotalStatCharge.class,
                Aggregation.match(criteria),
                //  project().andExpression("{$dateToString:{ format:'%Y-%m-%d',date: '$lastModifiedTime'}}").as("lastModifiedTime"),    //将ISODATE改变格式，并截取到天的字段；as后相当于起了一个别名
//                operations.add(Aggregation.project("registerTime").andExpression("{$dateToString: {date: { $add: {'$registerTime', [0]} }, format: '%Y-%m-%d'}}", new Date(28800000)).as("day"));
                Aggregation.project("rechargeTime", "uid", "rechargeType", "amount").andExpression("{$dateToString: {date: { $add: {'$rechargeTime', [0]} }, format: '%Y-%m-%d'}}", new Date(28800000)).as("rechargeTime"),
                Aggregation.group("rechargeTime", "uid", "rechargeType")
                        .first("uid").as("uid")
                        .first("rechargeType").as("rechargeType")
                        .first("rechargeTime").as("rechargeTime")
                        // .sum("amount").as("currencyAmount")
                        .sum("amount").as("amount"));
        AggregationResults<TotalStatCharge> rechargeRecord = mongoTemplate.aggregate(chargeRecordAggregation, "rechargeRecord", TotalStatCharge.class);
        return rechargeRecord.getMappedResults();
    }


    /**
     * 获取指定时间内用户的消费记录
     */
    private List<ActivityGoldConsume> getConsumeRecordInDuration(long startTime, long endTime) {
        Criteria criteria = Criteria.where("createAt").gte(startTime).lte(endTime);
        TypedAggregation<ActivityGoldConsume> aggregation = Aggregation.newAggregation(ActivityGoldConsume.class,
                Aggregation.match(criteria),
                Aggregation.project("uid", "uuid", "price", "scene", "num", "createAt"),
                Aggregation.group("uid")
                        .first("uid").as("uid")
                        .sum("price").as("price")
                        .first("uuid").as("uuid"));
        AggregationResults<ActivityGoldConsume> activityGoldConsume = mongoTemplate.aggregate(aggregation, "activityGoldConsume", ActivityGoldConsume.class);
        return activityGoldConsume.getMappedResults();
    }


    @GetMapping("/getUserConsumeData")
    public String getUserConsumeData() {
        List<ActivityGoldConsume> consumeList = null;
        try {
            consumeList = getConsumeRecordInDuration(1642749180000L, 1647846780000L);
            //userTotalChargeAmount = getUserBeforeChargeRecord(1617811199000L);
            JSONObject.toJSONString(consumeList);
        } catch (Exception e) {
            log.error("getMogonData", e);
            return "fail" + e.toString();
        }
        return "ok" + JSONObject.toJSONString(consumeList).toString();
    }


    @GetMapping("/getAllMessageStyle")
    public String getAllMessageStyle() {
        MessageStyleDict messageStyleDict = null;
        try {
            messageStyleDict = messageStyleDictMapper.selectById(1);
        } catch (Exception e) {
            log.error("exception message={}", e);
            return "fail";
        }
        return JSONObject.toJSONString(messageStyleDict);
    }

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;


    @GetMapping("/getKey")
    public String getKey() {
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent("one", 1);
            Object one = redisTemplate.opsForValue().get("one");
            System.out.println("result=" + result);
            System.out.println("one=" + one);
            return JSONObject.toJSONString("result=" + result + "one=" + one);
        } catch (Exception e) {
            log.error("exception message={}", e);
            return "fail";
        }

    }


    @Resource
    private PasswordEncoder passwordEncoder;


    @GetMapping("/testPwd")
    public String testPwd() {
        String password = "123456789";
//        加密
        String encode = passwordEncoder.encode(password);
        System.out.println(encode);
        //$2a$10$niDtgjTwZLbSaCWTdnccVuaG/igi.AFfEf9Ae2nBLMMHWBjmbk8/O
//        解密
        String pwd ="123456";
        boolean matches = passwordEncoder.matches(password, encode);
        System.out.println(matches);
        return "ok";

    }
}
